# -*- coding: utf-8 -*-
"""
@File: ttask.py
@Time: 2021/12/14 15:15
@Author: 鹄望潇湘
@desc: 

"""
import math
import random


class Task:
    def __init__(self, priority=0):
        self.player_name = None
        self.priority = priority
        pass

    def set_player_name(self, player_name):
        self.player_name = player_name

    def is_finish(self, global_state, player_state):
        return NotImplementedError()

    def get_action(self, global_state, player_state):
        return NotImplementedError()


class EatFoodTask(Task):
    def __init__(self):
        super(EatFoodTask, self).__init__(priority=0)
        self.continue_time = 0
        self.continue_border = 10
        self.last_action = None

    def get_action(self, global_state, player_state):
        self.continue_time = (self.continue_time+1) % self.continue_border
        if self.continue_time == 0:
            self.continue_border = self.continue_border+1
            return [None, None, -1]
        states = player_state[self.player_name]
        min_clone = [0, 0, 1000000]
        max_clone = [0, 0, 0]
        center_x = 0
        center_y = 0

        for item in states['overlap']['clone']:
            center_x = center_x + item[0]
            center_y = center_y + item[1]
            if item[2] < min_clone[2]:
                min_clone = item
            if item[2] > max_clone[2]:
                max_clone = item

        if random.randint(-5, 1) < 0:
            return [None, None, -1]

        center_x = center_x // len(states['overlap']['clone'])
        center_y = center_y // len(states['overlap']['clone'])

        target_x = 0
        target_y = 0
        result = None
        # 寻找最近的食物
        min_dis = 10000000
        foods = states['overlap']['food']
        for item in foods:
            if item[0] < 2*max_clone[2] or item[0] + 2*max_clone[2] >= global_state['border'][0] or \
                    item[1] < 2*max_clone[2] or item[1] + 2*max_clone[2] >= global_state['border'][1]:
                continue  # 防止球将边界周围的食物当做目标
            dis = self.get_distance((max_clone[0], max_clone[1]), (item[0], item[1]))
            if dis < min_dis:
                target_x = item[0]
                target_y = item[1]
                min_dis = dis
        result = [target_x - min_clone[0], target_y -min_clone[1], -1]
        # 寻找最近的刺球，刺球的优先级要高于食物
        min_dis = 10000
        for item in states['overlap']['thorns']:
            dis = self.get_distance((max_clone[0], max_clone[1]), (item[0], item[1]))
            if dis < min_dis and max_clone[2] > item[2]:
                target_x = item[0]
                target_y = item[1]
                min_dis = dis
                result = [target_x - max_clone[0], target_y - max_clone[1], -1]
            pass
        # 视野中既没有食物，也没有刺球
        if target_x == 0 and target_y == 0:
            x, y = 0, 0
            if min_clone[0] < 500:
                x = 1
            else:
                x = -1
            if min_clone[1] < 500:
                y = 1
            else:
                y = -1
            result = [x, y, -1]

        self.last_action = result
        return result

    def is_finish(self, global_state, player_state) -> bool:
        return False  # 没有其他任务时，就找食物吃

    def get_distance(self, p1, p2):
        return math.pow(p2[0] - p1[0], 2) + math.pow(p2[1] - p1[1], 2)


class MergeTask(Task):
    def __init__(self):
        super(MergeTask, self).__init__(priority=2)
        self.stoped = False

    def get_action(self, global_state, player_state):
        if self.stoped:
            return [None, None, 2]
        else:
            self.stoped = True
            return [None, None, 0]

    def is_finish(self, global_state, player_state) -> bool:
        state = player_state[self.player_name]
        if self.stoped and len(state['overlap']['clone']) <4:
            return True
        else:
            return False


class BreakTask(Task):
    def __init__(self):
        super(BreakTask, self).__init__(priority=1)
        self.has_break = False

    def get_action(self, global_state, player_state):
        self.has_break = True
        return [None, None, 4]

    def is_finish(self, global_state, player_state) -> bool:
        return self.has_break
